package com.example.baselib.utils;

import com.example.baselib.utils.log.LogUtils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import ohos.aafwk.ability.AbilityPackage;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

public class SPUtils {

    private static SPUtils spUtils;

    private static String spRootDir;
    //数据保存对象,key 文件名,value 数据
    private static Map<String, Map<String, Object>> cacheDataMap;
    private static Map<String, Object> currentMap;

    private SPUtils(AbilityPackage abilityPackage) {
        spRootDir = abilityPackage.getDataDir().getAbsolutePath();
        cacheDataMap = new HashMap<>();
    }


    public static synchronized void init(AbilityPackage abilityPackage) {
        if (spUtils == null) {
            spUtils = new SPUtils(abilityPackage);
        }
    }

    private static File createSPFile(String fileName) {
        File file = new File(spRootDir, fileName);
        if (!file.exists() || !file.isFile()) {
            File dir = new File(spRootDir);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            file = new File(dir, fileName);
            if (!file.exists()) {
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return file;
    }

    public static void openSPFile(String fileName) {
        if (spUtils == null) {
            throw new IllegalArgumentException("必须初始化 init() 方法");
        }
        if (cacheDataMap.containsKey(fileName)) {
            currentMap = cacheDataMap.get(fileName);
        } else {
            File file = new File(spRootDir, fileName);
            if (file.exists() && file.canWrite()) {
                try {
                    //获取文件缓存数据
                    String data = read(file);
                    currentMap = new Gson().fromJson(data, new TypeToken<Map<String, Object>>() {
                    }.getType());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (currentMap == null) {
                createSPFile(fileName);
                currentMap = new HashMap<>();
            }
            cacheDataMap.put(fileName, currentMap);
        }
    }


    public static void put(String key, String value) {
        if (currentMap == null) {
            LogUtils.w("添加数据失败,请调用 openSPFile() 方法");
            return;
        }
        String fileName = "";
        for (Map.Entry<String, Map<String, Object>> entry : cacheDataMap.entrySet()) {
            if (entry.getValue() == currentMap) {
                fileName = entry.getKey();
                break;
            }
        }
        if (TextUtils.isEmpty(fileName)) {
            LogUtils.d("获取保存异常,添加数据失败");
            return;
        }
        currentMap.put(key, value);
        String data = map2String(currentMap);

        boolean save = write(data, new File(spRootDir, fileName));
        LogUtils.i("数据写入文件状态:%s", save ? "成功" : "失败");
    }

    /**
     * 获取数据
     *
     * @param key      key
     * @param defValue 默认值
     * @return T
     */
    public static <T extends Object> T get(String key, Object defValue) {
        if (currentMap == null) {
            LogUtils.w("返回默认值:%s,请调用 openSPFile() 方法", defValue);
            return (T) defValue;
        }
        Object data = defValue;
        if (currentMap.containsKey(key)) {
            data = currentMap.get(key);
        }
        LogUtils.i("读取缓存数据,key = %s,value = %s,默认值:%s", key, data, defValue);
        return (T) data;
    }

    //数据转换
    private static String map2String(Map<String, Object> stringMap) {
        if (stringMap != null && stringMap.size() > 0) {
            return new Gson().toJson(stringMap);
        }
        return null;
    }

    //写入本地文件
    private static boolean write(String str, File file) {
        OutputStream out = null;
        try {
            if (str != null && str.length() > 0) {
                LogUtils.d("数据写入文件名称:%s", file.getName());
                out = new BufferedOutputStream(new FileOutputStream(file, false));
                out.write(str.getBytes());
                return true;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    //读取本地文件内容
    private static String read(File file) {
        InputStream stream = null;
        try {
            String data;
            int len;
            byte[] buffer = new byte[2048];
            StringBuffer sb = new StringBuffer();
            stream = new BufferedInputStream(new FileInputStream(file));
            while ((len = stream.read(buffer)) != -1) {
                // 写入文件
                data = new String(buffer, 0, len);
                sb.append(data);
            }
            return sb.toString();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (stream != null)
                    stream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

}
